#include<iostream>
#include<cassert>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>

int main()
{
    int pipes[2];
    int ret = pipe(pipes);
    // 现在创建一个管道文件，对应的文件描述符为 3 和 4 
    assert(ret == 0);
    
    int pid = fork();
    if(pid == 0)
    {
       close(pipes[0]);
       int cnt = 1;
       while(true)
       {
       //通信的通道已经搭建好，现在只需要在这里进行通信即可
       if(cnt == 2)
       {
          close(pipes[1]);
          break;
       }
       

       char buffer[1024];
       sprintf(buffer, "我是子进程，我的pid是：%d,我是第%d次写入", getpid(),cnt);
       cnt++;
       write(pipes[1], buffer,strlen( buffer) ); // 这里不需要 -1 , 没被解释成C类型的字符串，所以不用变

       sleep(2);

       }
       close(pipes[1]);
       exit(0);
    }
    
    close(pipes[1]);
    while(true)
    {
        //从零号管道里读出来
        char buffer[1024];
        ssize_t    n =  read(pipes[0], buffer, sizeof(buffer) - 1 ); // 这里被解释成了C类型字符串
        // read 其实是一个阻塞读取，当buffer里面没东西的时候，会阻塞等待资源
        if(n > 0)
        {
            std::cout << "父进程读取成功，父进程pid" << getpid() << std::endl;
        }
        if(n == 0)
        {
            std::cout << "检测到写通道关闭，读通道立即关闭！" << std::endl;
            break;
        }

        printf("%s\n",buffer);
        sleep(1);
    }
    close(pipes[0]);

    int status;
    int jugdePid = waitpid(pid , &status, 0);
    if(jugdePid == pid)
    {
        std::cout << "进程等待成功" << std::endl;
        printf("退出信号 ： %d\n" , status & (0x007F)  );
        
        if(status & (0x007F) != 0)
        std::cout << "异常退出！" << std::endl;
        else
        std::cout << "正常退出"   << std::endl;

    }

    return 0;
}